from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form, Query
from fastapi.responses import StreamingResponse, JSONResponse
from sqlalchemy.orm import Session
from typing import Optional, Dict, Any, List
import io
import base64
import json
import re
from datetime import datetime

from database import get_db
from services import file_service, report_service, merchant_service, data_service
from models import Report, Merchant, FileUpload
import schemas

router = APIRouter()

# 统一响应格式
def create_response(code: int = 200, message: str = "成功", data: Any = None):
    return {
        "code": code,
        "message": message,
        "data": data
    }


@router.post("/upload", response_model=schemas.Response)
async def upload_file(
    file: Optional[UploadFile] = File(None),
    merchant_id: int = Form(...),
    file_type: int = Form(...),  # 1-抖音来客, 2-抖音生意经
    merchant_name: Optional[str] = Form(None),
    file_content: Optional[str] = Form(None),
    filename: Optional[str] = Form(None),
    remark: Optional[str] = Form(None),
    db: Session = Depends(get_db)
):
    """
    上传文件
    
    - **file**: 上传的文件（可选，如果提供file_content则不需要）
    - **merchant_id**: 商户ID
    - **file_type**: 文件类型：1-抖音来客, 2-抖音生意经
    - **merchant_name**: 商户名称(可选)
    - **file_content**: 文件内容字符串(可选)
    - **filename**: 文件名称(可选，当使用file_content时必须提供)
    - **remark**: 备注信息
    """
    try:
        # 检查是否存在抖音生意经的上传记录
        existing_business_file = db.query(FileUpload).filter(
            FileUpload.merchant_id == merchant_id,
            FileUpload.file_type == 2,  # 抖音生意经
            FileUpload.status == 1
        ).first()
        
        # 首先检查商户是否存在
        merchant = merchant_service.get_merchant_by_id(db, merchant_id)
        
        if not merchant:
            # 如果商户不存在，创建一个新商户
            merchant_data = {
                "id": merchant_id,  # 使用传入的ID
                "name": merchant_name if merchant_name else f"商户{merchant_id}",
                "code": str(merchant_id),  # 转换为字符串，确保兼容性
                "contact_person": "自动创建",
                "contact_phone": "",
                "status": 1,
                "remark": "系统自动创建的商户"
            }
            merchant = merchant_service.create_merchant_with_id(db, merchant_data)
        elif file_type == 2 and merchant_name:
            # 如果是抖音生意经，则更新商户名称，强制使用服务层更新
            merchant_data = {
                "name": merchant_name
            }
            merchant = merchant_service.update_merchant(db, merchant_id, merchant_data)
            if not merchant:
                return create_response(code=500, message="更新商户名称失败")
        elif file_type == 1 and merchant_name and not existing_business_file:
            # 如果是抖音来客且没有已存在的抖音生意经记录，才使用其商户名称
            merchant_data = {
                "name": merchant_name
            }
            merchant = merchant_service.update_merchant(db, merchant_id, merchant_data)
            if not merchant:
                return create_response(code=500, message="更新商户名称失败")
            
        # 确保刷新merchant对象，以获取最新状态
        db.refresh(merchant)
            
        # 确保商户的报告记录存在，获取报告ID
        report = db.query(Report).filter(Report.merchant_id == merchant_id).order_by(Report.id.desc()).first()
        
        if not report:
            # 如果报告不存在，创建一个新报告
            # 生成唯一的报告编码
            report_code = f"R{merchant_id}_{datetime.now().strftime('%Y%m%d%H%M%S')}"
            report_data = {
                "merchant_id": merchant_id,
                "report_code": report_code,
                "report_name": f"{merchant.name}自动创建报告",
                "report_date": "2099-12-31",  # 使用未来日期作为默认值
                "expected_file_count": 2,
                "operator": "system",
                "remark": f"为{merchant.name}自动创建的报告"
            }
            report = report_service.create_report(db, report_data)
        elif file_type == 2 and merchant_name:  # 如果是抖音生意经且提供了商户名称
            # 更新报告名称，保持与商户名称一致
            report.report_name = f"{merchant.name}自动创建报告"
            db.commit()
            db.refresh(report)  # 刷新数据库对象
            
        # 处理文件内容 - 优先使用传入的字符串内容
        if file_content is not None:
            # 如果提供了字符串内容，直接使用它
            content_bytes = file_content.encode('utf-8')
            file_name = filename or f"商户数据_{merchant_id}_{file_type}.md"
            file_format = "md"
        elif file is not None:
            # 否则从上传的文件中读取内容
            content_bytes = await file.read()
            file_name = file.filename
            file_format = file.filename.split(".")[-1] if "." in file.filename else ""
        else:
            # 如果既没有提供文件也没有提供内容，则返回错误
            return create_response(code=400, message="必须提供文件或文件内容")
            
        file_info = {
            "merchant_id": merchant_id,
            "report_id": report.id,  # 使用查询到的或新创建的报告ID
            "file_name": file_name,
            "file_size": len(content_bytes),
            "file_type": file_type,
            "file_format": file_format,
            "store_type": 1,  # 默认使用数据库存储
            "file_content": content_bytes,
            "remark": remark if remark else f"商户{merchant_id}的{'抖音来客' if file_type == 1 else '抖音生意经'}文件",
            "operator": "system"
        }
        
        # 上传文件，这里会覆盖同一商户同类型的旧文件
        result = file_service.upload_file(db, file_info)
        
        return create_response(
            message="上传成功",
            data={
                "fileId": result.id,
                "fileName": result.file_name,
                "fileType": result.file_type,
                "fileSize": result.file_size,
                "uploadTime": result.upload_time.strftime("%Y-%m-%d %H:%M:%S"),
                "fileFormat": result.file_format
            }
        )
    except Exception as e:
        return create_response(code=500, message=f"文件上传失败: {str(e)}")

@router.get("/merchant/{merchant_id}", response_model=schemas.Response)
async def get_merchant_files(
    merchant_id: int,
    db: Session = Depends(get_db)
):
    """
    获取指定商户的所有MD文件
    
    - **merchant_id**: 商户ID
    """
    try:
        # 获取该商户的所有有效文件
        files = file_service.get_merchant_files(db, merchant_id)
        
        if not files or len(files) == 0:
            return create_response(
                code=404,
                message=f"未找到商户ID为{merchant_id}的文件",
                data={"files": []}
            )
        
        # 处理文件内容，转换为markdown格式
        file_contents = []
        for file in files:
            content = None
            if file.file_content:
                try:
                    # 将二进制数据解码为UTF-8文本
                    content = file.file_content.decode('utf-8')
                    
                    # 增强MD内容，优化数组显示
                    
                    # 确保文件内容是有效的markdown格式
                    if not content.startswith('#'):
                        # 如果不是以标题开始的，添加标题
                        file_type_name = "抖音来客" if file.file_type == 1 else "抖音生意经"
                        content = f"# {file_type_name}数据报告\n\n{content}"
                except UnicodeDecodeError:
                    content = f"# 无法解码文件内容\n\n文件 {file.file_name} 包含非文本数据，无法显示。"
            else:
                content = "# 文件内容为空"
            
            file_contents.append({
                "fileId": file.id,
                "fileName": file.file_name,
                "fileType": file.file_type,
                "fileFormat": file.file_format,
                "content": content,  # 增强后的markdown文本
                "uploadTime": file.upload_time.strftime("%Y-%m-%d %H:%M:%S")
            })
        
        return create_response(
            message="获取成功",
            data={"files": file_contents}
        )
    except Exception as e:
        return create_response(code=500, message=f"获取文件失败: {str(e)}")

@router.get("/list", response_model=schemas.Response)
async def list_files(
    merchant_id: Optional[int] = None,
    file_type: Optional[int] = None,
    status: int = 1,
    page_num: int = 1,
    page_size: int = 10,
    db: Session = Depends(get_db)
):
    """
    获取文件列表
    
    - **merchant_id**: 商户ID
    - **file_type**: 文件类型：1-抖音来客, 2-抖音生意经
    - **status**: 文件状态：0-无效，1-有效(默认)
    - **page_num**: 页码，从1开始，默认1
    - **page_size**: 每页记录数，默认10
    """
    try:
        filters = {
            "merchant_id": merchant_id,
            "file_type": file_type,
            "status": status
        }
        # 移除None值
        filters = {k: v for k, v in filters.items() if v is not None}
        
        result = file_service.get_file_list(db, filters, page_num, page_size)
        
        return create_response(
            message="查询成功",
            data=result
        )
    except Exception as e:
        return create_response(code=500, message=f"查询失败: {str(e)}")

@router.get("/download/{file_id}")
async def download_file(
    file_id: int,
    db: Session = Depends(get_db)
):
    """
    下载文件
    
    - **file_id**: 文件ID
    """
    try:
        file_info = file_service.get_file_by_id(db, file_id)
        if not file_info:
            raise HTTPException(status_code=404, detail="文件不存在")
        
        # 确保文件内容存在
        if not file_info.file_content:
            raise HTTPException(status_code=404, detail="文件内容为空")
        
        # 确定内容类型
        content_type = file_service.get_content_type(file_info.file_format)
        
        # 创建响应
        return StreamingResponse(
            io.BytesIO(file_info.file_content),
            media_type=content_type,
            headers={
                "Content-Disposition": f'attachment; filename="{file_info.file_name}"',
                "Access-Control-Allow-Origin": "*"  # 允许跨域访问
            }
        )
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"下载失败: {str(e)}")

@router.delete("/{file_id}", response_model=schemas.Response)
async def delete_file(
    file_id: int,
    db: Session = Depends(get_db)
):
    """
    删除文件
    
    - **file_id**: 文件ID
    """
    try:
        success = file_service.delete_file(db, file_id)
        if success:
            return create_response(message="删除成功")
        else:
            return create_response(code=404, message="文件不存在或删除失败")
    except Exception as e:
        return create_response(code=500, message=f"删除失败: {str(e)}") 